from django.shortcuts import render, render_to_response
from django.template import RequestContext
from django.http import HttpResponse, HttpResponseRedirect
from django.conf import settings
from django.template.context_processors import csrf

from .models import *

import os, datetime, json, sys, qrcode, hashlib

class ChatAction :
	def record(request) :
		dict_render = { 'request' : request, }
		dict_render.update(csrf(request))
		return dict_render

	def comment_total() :
		return MessageData.objects.count()

	def chat(time_update, session, history, float_update) :
		'如果没有content'
		if not history and float(float_update) == 0.0 :
			qry = MessageData.objects.filter \
				(time_create__gte=datetime.datetime.now() - datetime.timedelta \
				(1, 0, 0), session=session).order_by('time_create')
		else :
			qry = MessageData.objects.filter(time_create__gte=time_update, 
				session=session).order_by('time_create')
		chat_list = []
		for i in qry :
			chat_list += [{
				'msg_id': hashlib.md5(('41e1cb9f2474b10e%d092723a8b5dbb8e5' % \
										i.id).encode()).hexdigest(), 
				'uuid': i.sender_uuid, 
				'nickname': i.sender_name, 
				'content': i.content, 
				'time_update': ChatAction.datetime_find(i.time_create), 
			}]
		return chat_list

	def duplicate_detect(sender_name, content, sender_uuid, session) :
		'检测是否有短时间（10秒钟内）重复发送的信息'
		qry = MessageData.objects.filter(sender_name=sender_name, 
					content=content, sender_uuid=sender_uuid, session=session)
		ten_sec_ago = datetime.datetime.now() - datetime.timedelta(0, 10, 0)
		if qry.filter(time_create__gte=ten_sec_ago).exists() :
			return True
		return False

	def datetime_find(time) :
		'返回简短时间'
		time += datetime.timedelta(0,8*3600,0)
		mon = int(time.strftime('%m'))
		day = int(time.strftime('%d'))
		date_string = "%d月%d日 " % (mon, day)
		time_string = time.strftime('%H:%M')
		return date_string + time_string

	def dict_render(request) :
		dict_render = ChatAction.record(request)
		dict_render.update({
			'nickname': request.session.get('nickname', ''), 
			'uuid': request.session.get('uuid', ''), 
			'no_audio': request.session.get('no-audio', ''), 
		})
		return dict_render

	def session_certify(request, session) :
		'用户是否可以访问session'
		if not session :
			return True
		if request.session.get('session-%s' % session, '') == 'True' :
			return True
		else :
			return False

	def dangerous_check(s) :
		'str是否包含非法字符'
		for i in s :
			if i not in '-0123456789' + \
				'abcdefghijklmnopqrstuvwxyz' + \
				'ABCDEFGHIJKLMNOPQRSTUVWXYZ' :
				return True
		return False

	def qrcode_create(session, token) :
		'''
			生成qrcode
			访问
				/media/images/qrcode/{{ session }}.png
				/media/images/qrcode/{{ session }}.{{ token }}.png
		'''
		val1 = 'http://t.hcc.io/nickname/?session=%s&token=%s' % (session, token)
		val2 = 'http://t.hcc.io/nickname/?session=%s' % session
		media_route = settings.MEDIA_ROOT + 'images/qrcode/'
		dir1 = '%s%s.%s.png' % (media_route, session, token)
		dir2 = '%s%s.png' % (media_route, session)
		try :
			if not os.path.exists(dir1) :
				qrcode.make(val1).save(dir1)
			if not os.path.exists(dir2) :
				qrcode.make(val2).save(dir2)
		except Exception as e:
			print('error: %s' % repr(e))
		return True

class ChatViews :
	def message(request) :
		'接受投递message[POST]'
		dict_render = ChatAction.record(request)
		nickname = request.session.get('nickname', '')
		suid = request.POST.get('uuid', '')
		request.session['uuid'] = suid
		content = request.POST.get('content', '')
		session = request.POST.get('session', '')
		if not ChatAction.session_certify(request, session) :
			return HttpResponseRedirect('/')
		if not suid or not content :
			return HttpResponseRedirect('/nickname/')
		if not nickname :
			nickname = suid[0:8]
		if ChatAction.duplicate_detect(nickname, content, suid, session) :
			return HttpResponse('failed: duplication detected')
		MessageData(sender_name=nickname, content=content, sender_uuid=suid, 
					session=session).save()
		return HttpResponse('success: congradulations')

	def nickname(request) :
		'更改nickname'
		dict_render = ChatAction.dict_render(request)
		session = request.POST.get('session', '')
		token = request.POST.get('token', '')
		if not session :
			session = request.GET.get('session', '')
		if not token :
			token = request.GET.get('token', '')
		if ChatAction.dangerous_check(session + token) :
			session = ''
			token = ''
		dict_render['session'] = session
		dict_render['token'] = token
		if request.session.get('nickname', '') :
			return HttpResponseRedirect('/?session=%s&token=%s' % (session, token))
		if request.method == 'POST' :
			request.session['nickname'] = request.POST.get('nickname', '');
#			return HttpResponseRedirect('/?session=%s&token=%s' % (session, token))
			if request.session.get('nickname', '') :
				return HttpResponseRedirect('/?token=%s&session=%s' % (token, session))
			else :
				dict_render['content'] = '似乎没有输入昵称'
				return render_to_response('nickname.html', dict_render)
		else :
			return render_to_response('nickname.html', dict_render)

	def chat(request, session='') :
		'''
			返回网页[GET] 和 message[POST]
			GET['history'] = 'true' 表示加载历史
		'''
		dict_render = ChatAction.dict_render(request)
		dict_render['session'] = session
		if not request.session.get('nickname', '') :
			return HttpResponseRedirect('/nickname/?session=%s' % session)
		if not ChatAction.session_certify(request, session) :
			return HttpResponseRedirect('/?session=%s' % session)
		if request.method == 'POST' :
			float_update = request.POST.get('time_update', '')
			time_update = datetime.datetime.fromtimestamp(float(float_update))
			history = bool(request.POST.get('history', ''))
			message_list = ChatAction.chat \
				(time_update, session, history, float_update)
			time_current = datetime.datetime.now()
			current_stamp = time_current.timestamp()
			result = json.dumps({
				'message_list': message_list, 
				'time_update': current_stamp, 
			})
			return HttpResponse(result, content_type="application/json")
		else:
			if session :
				qry = SessionInfo.objects.filter(name=session)[0]
				dict_render['qrcode_token'] = \
					'/media/images/qrcode/%s.%s.png' % (qry.name, qry.token)
				dict_render['qrcode_session'] = \
					'/media/images/qrcode/%s.png' % qry.name
			else :
				dict_render['qrcode_token'] = '/static/images/default-session.png'
			dict_render['history'] = bool(request.GET.get('history', ''))
			dict_render['session_page'] = True
			return render_to_response('comment.html', dict_render)

	def session(request) :
		'切换session'
		dict_render = ChatAction.dict_render(request)
		session = request.POST.get('session', '')
		token = request.POST.get('token', '')
		if not session :
			session = request.GET.get('session', '')
		if not token :
			token = request.GET.get('token', '')
		dict_render['session'] = session
		dict_render['token'] = token
		if ChatAction.dangerous_check(session + token) :
			dict_render['content'] = '包含非法字符'
			return render_to_response('session.html', dict_render)
		if not request.session.get('nickname', '') :
			return HttpResponseRedirect('/nickname/?session=%s&token=%s' % \
					(session, token))
		if request.method == 'POST' or session :
			if session :
				qry = SessionInfo.objects.filter(name=session)
				if qry :
					if qry[0].token == token or \
						ChatAction.session_certify(request, session) :
						request.session['session-%s' % session] = 'True'
					else :
						dict_render['content'] = 'Token 不正确'
						return render_to_response('session.html', dict_render)
				else :
					dict_render['content'] = 'Session 不存在，可尝试创建会话'
					return render_to_response('session.html', dict_render)
				return HttpResponseRedirect('/s/%s/' % session)
			else :	# session == ''
				return HttpResponseRedirect('/s/')
		return render_to_response('session.html', dict_render)

	def session_create(request) :
		dict_render = ChatAction.dict_render(request)
		session = request.POST.get('session', '')
		token = request.POST.get('token', '')
		if not session :
			session = request.GET.get('session', '')
		if not token :
			token = request.GET.get('token', '')
		dict_render['session'] = session
		dict_render['token'] = token
		if ChatAction.dangerous_check(session + token) :
			dict_render['content'] = '包含非法字符'
			return render_to_response('session_create.html', dict_render)
		if request.method == 'POST' :
			qry = SessionInfo.objects.filter(name=session)
			if qry :
				dict_render['content'] = 'Session已经创建，请直接登陆'
				return render_to_response('session_create.html', dict_render)
			if not (1 <= len(session) <= 40) :
				dict_render['content'] = 'Session ID 长度不合适'
				return render_to_response('session_create.html', dict_render)
			if len(token) < 4 or len(token) > 10 :
				dict_render['content'] = 'Token 长度不对（应该至少4位）'
				return render_to_response('session.html', dict_render)
			SessionInfo(name=session, token=token).save()
			ChatAction.qrcode_create(session, token)
			request.session['session-%s' % session] = 'True'
			return HttpResponseRedirect('/s/%s/' % session)
		return render_to_response('session_create.html', dict_render)

	def audio(request) :
		'设置声音'
		dict_render = ChatAction.record(request)
		if request.GET.get('audio', '') == 'off' :
			request.session['no-audio'] = 'true'
		elif request.GET.get('audio', '') == 'on' :
			request.session['no-audio'] = ''
		session = request.GET.get('session', '')
		if session and not ChatAction.dangerous_check(session) :
			return HttpResponseRedirect('/s/%s/' % session)
		return HttpResponseRedirect('/')

	def export(request) :
		'导出会话文本'
		dict_render = ChatAction.record(request)
		session = request.GET.get('session', '')
		if not ChatAction.session_certify(request, session) :
			return HttpResponseRedirect('/?session=%s' % session)
		chat_list = ChatAction.chat \
						(datetime.datetime.fromtimestamp(0), session, True, 0)
		response = ''
		for i in chat_list :
			response += '%s\t%s\t%s\n' % \
				(i['time_update'], i['nickname'], i['content'])
		resp = HttpResponse(response, content_type='text/plain')
		uagent = request.META.get('HTTP_USER_AGENT', 'unknown_AGENT')
		fraw = '[%s].txt' % session
		if 'Trident' in uagent or 'Chrome' in uagent or 'AppleWebKit' in uagent:
			resp['Content-Disposition'] = 'attachment; filename=%s' % fraw
		else :
			resp['Content-Disposition'] = "attachment; filename*=\"utf8''%s\"" % fraw
		return resp

